<?php

namespace Core;

use Core\Log;

/**
 * 输入解析
 *
 * @author lxc
 */
class Request
{

	private $request = '';
	private $host = '';
	private $head = '';
	private $body = '';
	private $url = '';
	private $http_type = '';
	private $get = [];
	private $post = [];
	private $files = [];
	private $controller = '';
	private $action = '';
	private $fragment = '';
	private $fid = '';
	private $send_file_path = '';
	private $head_list = [];

	public function __construct($request = '', $fid)
	{
		$this->request = $request;
		$this->fid = $fid;
		list($this->head, $this->body) = explode("\r\n\r\n", $this->request);
		$this->parseHead();
		$this->parseURL();
		$this->parseBody();
	}

	/**
	 *
	 * @param type $key
	 * @return type
	 */
	public function get($key)
	{
		if (isset($this->$key))
			return $this->$key;
		else
			return null;
	}

	private function parseHead()
	{
		$head_arr = explode("\r\n", $this->head);
		//第一行 GET /index.html HTTP/1.1
		list($this->http_type, $this->url, $http_version) = explode(' ', array_shift($head_arr));
		$head_list = [];
		foreach ($head_arr as $v) {
			list($key, $val) = explode(': ', $v);
			$head_list[$key] = $val;
		}
		$this->head_list = $head_list;
		//第二行 Host: framework.lxc.com
		$this->host = $this->head_list['Host'];
	}

	private function parseBody()
	{
		if (empty($this->body)) {
			$this->post = null;
			return true;
		}

		$content_type = 'text/html'; // 'application/json'
		if ($content_type == 'text/html') {
			parse_str($this->body, $this->post);
			return true;
		}
	}

	private function parseURL()
	{
		$data = parse_url($this->url);


		$app_root_dir = dirname(__DIR__) . Config::getInstance()->get('common.app_root_dir');
		if (is_file($app_root_dir . $data['path'])) {
			return $this->send_file_path = $app_root_dir . $data['path'];
		}

		list($path, $query, $this->fragment) = [$this->trim_path_extention($data['path']), isset($data['query']) ? explode('&', $data['query']) : [], isset($data['fragment']) ? urldecode($data['fragment']) : ''];
		$this->get = [];
		foreach ($query ?: [] as &$v) {
			list($key, $val) = explode('=', $v);
			$this->get[$key] = urldecode($val);
		}
		unset($query);
		if ($path == '')
			$path = '/';

		$default_controller = Config::getInstance()->get('controller.default_controller');
		$default_action = Config::getInstance()->get('controller.default_action');
		if ($path == '/') {
			list($this->controller, $this->action) = [$default_controller, $default_action];
		} else {
			$path_arr = explode('/', $path);
			array_shift($path_arr);
			$this->controller = empty($path_arr) ? $default_controller : array_shift($path_arr);
			$this->action = empty($path_arr) ? $default_action : array_shift($path_arr);
		}

		//检查是否是允许请求的控制器
		if (!in_array(strtolower($this->controller), ['pub', 'index', 'msg']))
			return $this->send_file_path = $app_root_dir . $data['path'];

		if (!empty($path_arr)) {
			$ext = array_chunk($path_arr, 2);
			foreach ($ext as $q) {
				list($name, $value) = $q;
				$this->get[urldecode($name)] = $value ? urldecode($value) : '';
			}
		}
	}

	private function trim_path_extention($path)
	{
		$path = strtolower($path);
		$ext_err = ['.html', '.htm', '.php'];
		$len = strlen($path);
		foreach ($ext_err as $v) {
			$len_ext = strlen($v);
			if (substr($path, $len - $len_ext) == $v)
				return substr($path, 0, $len - $len_ext);
		}
		return $path;
	}

}
